#include "EffectManager.h"

EffectManager::EffectManager(void) : setEffect(NULL),  setHandle(NULL)
{
}

EffectManager::~EffectManager(void)
{
	for(vector<LPD3DXEFFECT>::const_iterator itr = effects.begin(); itr != effects.end(); itr++) 
	{
		LPD3DXEFFECT eff = (LPD3DXEFFECT)*itr;
		eff->Release();
	}	
	effects.clear();
	effectHandles.clear();
	fileNames.clear();
}

bool EffectManager::loadEffectFile(const LPDIRECT3DDEVICE9 p_dx_Device, const LPCWSTR fileName)
{
	HRESULT hr = NULL;
	ID3DXBuffer* errorBuffer = NULL;
	ID3DXEffect* effect = NULL;
	D3DXHANDLE effectHandle = NULL;

	hr = D3DXCreateEffectFromFile(
		p_dx_Device, // associated device
		fileName, // effect filename
		0, // no preprocessor definitions
		0, // no ID3DXInclude interface
		D3DXSHADER_DEBUG, // compile flags
		0, // don't share parameters
		&effect, // return effect interface pointer
		&errorBuffer); // return error messages

	if(FAILED(hr))
	{
		SHOW_ERROR_MSG(hr, L"Failed to load a fx file.");
		// output any error messages
		if(errorBuffer)
		{
			int size = mbstowcs(0, (char *)errorBuffer->GetBufferPointer(), 0);
			wchar_t *input = new wchar_t[size];
			mbstowcs(input, (char *)errorBuffer->GetBufferPointer(), size);
			if(FAILED(hr))
			{
				MessageBox(0, input, 0, 0);
			}
			errorBuffer->Release();
		}
		return false;
	}

	D3DXEFFECT_DESC desc;
	effect->GetDesc(&desc);

	// TODO: handle multiple techniques in one file
	effectHandle = effect->GetTechnique(0);

	fileNames.push_back(fileName);
	effects.push_back(effect);
	effectHandles.push_back(effectHandle);
	return true;
}

void EffectManager::getEffectAndHandle(LPD3DXEFFECT &effectIn, D3DXHANDLE &in, const LPCWSTR fileName)
{
	std::vector<LPCWSTR>::const_iterator itr;
	int index = 0;
	for(itr = fileNames.begin(); 
		itr != fileNames.end();
		itr++) 
	{
		LPCWSTR file = (LPCWSTR)*itr;
		if (wcscmp(file, fileName) == 0) {
			effectIn = effects[index];
			in = effectHandles[index];
			return;
		}
		index++;
	}
}

HRESULT EffectManager::setupEffect(const LPCWSTR fileName)
{
	std::vector<LPCWSTR>::const_iterator itr;
	int index = 0;
	for(itr = fileNames.begin(); 
		itr != fileNames.end();
		itr++) 
	{
		LPCWSTR file = (LPCWSTR)*itr;
		if (wcscmp(file, fileName) == 0) {
			setEffect = effects[index];
			setHandle = effectHandles[index];
			return setEffect->SetTechnique(setHandle);
		}
		index++;
	}
	return 0;
}